<ui:composition template="/WEB-INF/templates/showcase.xhtml"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:c="http://java.sun.com/jsp/jstl/core"
	xmlns:o="http://omnifaces.org/ui"
	xmlns:of="http://omnifaces.org/functions"
>
	<ui:define name="description">
		<p>
			The <code>&lt;o:validator&gt;</code> basically extends the <code>&lt;f:validator&gt;</code> tag family with the
			possibility to evaluate EL in all attributes during view render time instead of during view build time. 
			This allows the developer to evaluate the attributes dynamically on a per request basis or even on a per
			iteration basis inside a repeater component, such as the <code>disabled</code> attribute.
		</p>
		<pre class="prettyprint"><code class="xhtml">
&lt;o:validator validatorId="someValidatorId" disabled="\#{param.disableValidation}" /&gt;
		</code></pre>
		<p>
			When you specify for example the standard <code>&lt;f:validateLength&gt;</code> by
			<code>validatorId="javax.faces.Length"</code>, then you'll be able to use all its attributes such as
			<code>minimum</code> and <code>maximum</code> as per 
			<a href="http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/validateLength.html" rel="ext">its documentation</a>,
			but then with the possibility to supply render time value expressions.
		</p>
		<pre class="prettyprint"><code class="xhtml">
&lt;o:validator validatorId="javax.faces.Length" minimum="\#{item.minimum}" maximum="\#{item.maximum}" /&gt;
		</code></pre>
		<p>
			The validator ID of all standard JSF validators can be found in 
			<a href="http://docs.oracle.com/javaee/6/api/javax/faces/validator/package-summary.html" rel="ext">their javadocs</a>.
			First go to the javadoc of the class of interest, then go to <code>VALIDATOR_ID</code> in its field summary 
			and finally click the Constant Field Values link to see the value.
		</p>
		<p>
			In the below demo, the validators are supposed to be disabled based on the currently selected contact method.
			Change the contact method to phone and enter a valid phone number, e.g. <code>0123456789</code>, you'll see
			that with the <code>&lt;f:validator&gt;</code>, the email validator is still been used because that was the
			one which was set during view build time which would due to
			<a href="http://java.net/jira/browse/JAVASERVERFACES-1492">JSF issue 1492</a>
			use a completely different view scoped bean instance. The <code>&lt;o:validator&gt;</code> allows a render
			time evaluation of attributes and hence works as intuitively expected as it wouldn't create a brand new
			instance of the view scoped bean, but just reuse the one as is been used during the ajax request.
		</p>
		<p>
			For another related use case, checkout the 
			<h:link outcome="converter"><code>&lt;o:converter&gt;</code> showcase page</h:link>.
		</p>
		<p>
			Further, the <code>&lt;o:validator&gt;</code> also allows setting the validation message on a per-validator basis
			by the <code>message</code> attribute. This is not possible with <code>&lt;f:validator&gt;</code> and the 
			<code>validatorMessage</code> attribute of the parent input component applies to <i>all</i> validators.
			Note that the <code>message</code> attribute of <code>&lt;o:validator&gt;</code> has <i>no</i> effect when the
			<code>validatorMessage</code> attribute of the parent input component has already been set.
		</p>
	</ui:define>

	<ui:define name="demo">
		<h3>With <code>&lt;f:validator&gt;</code> - phone is still validated as email</h3>
		<h:form>
			<h:panelGrid columns="3">
				<o:outputLabel for="contact" value="Contact" />
				<h:panelGroup>
					<h:selectOneMenu id="contactMethod" value="#{validatorBean.contactMethod1}">
						<f:selectItem itemLabel="Email" itemValue="email" />
						<f:selectItem itemLabel="Phone" itemValue="phone" />
						<f:ajax render="contact contactMessage" />
					</h:selectOneMenu>
					<h:inputText id="contact" required="true" requiredMessage="Please enter #{validatorBean.contactMethod1}">
						<f:validator validatorId="emailValidator" disabled="#{validatorBean.contactMethod1 != 'email'}" />
						<f:validator validatorId="phoneValidator" disabled="#{validatorBean.contactMethod1 != 'phone'}" />
					</h:inputText>
				</h:panelGroup>
				<h:message id="contactMessage" for="contact" />
			
				<h:panelGroup />
				<h:commandButton value="Submit">
					<f:ajax execute="@form" render="@form" />
				</h:commandButton>
				<h:panelGroup>
					<h:outputText value="OK!" rendered="#{facesContext.postback and not facesContext.validationFailed}" />
				</h:panelGroup>
			</h:panelGrid>
		</h:form>

		<hr />

		<h3>With <code>&lt;o:validator&gt;</code> - disabled attribute now works request based</h3>
		<h:form>
			<h:panelGrid columns="3">
				<o:outputLabel for="contact" value="Contact" />
				<h:panelGroup>
					<h:selectOneMenu id="contactMethod" value="#{validatorBean.contactMethod2}">
						<f:selectItem itemLabel="Email" itemValue="email" />
						<f:selectItem itemLabel="Phone" itemValue="phone" />
						<f:ajax render="contact contactMessage" />
					</h:selectOneMenu>
					<h:inputText id="contact" required="true" requiredMessage="Please enter #{validatorBean.contactMethod2}">
						<o:validator validatorId="emailValidator" disabled="#{validatorBean.contactMethod2 != 'email'}" />
						<o:validator validatorId="phoneValidator" disabled="#{validatorBean.contactMethod2 != 'phone'}" />
					</h:inputText>
				</h:panelGroup>
				<h:message id="contactMessage" for="contact" />
			
				<h:panelGroup />
				<h:commandButton value="Submit">
					<f:ajax execute="@form" render="@form" />
				</h:commandButton>
				<h:panelGroup>
					<h:outputText value="OK!" rendered="#{facesContext.postback and not facesContext.validationFailed}" />
				</h:panelGroup>
			</h:panelGrid>
		</h:form>

		<hr />

		<h3>Set validator message on a per-validator basis</h3>
		<h:form>
			<h:messages />
			<h:dataTable binding="#{table}" value="#{validatorBean.entities}" var="entity">
				<h:column>
					<c:set var="label" value="Input #{table.rowIndex + 1}" />
					<o:outputLabel for="input" value="#{label}" />
				</h:column>
				<h:column>
					<h:inputText id="input" value="#{entity.value}" required="true" requiredMessage="#{label} is required">
						<o:validator validatorId="javax.faces.Length" minimum="5" message="{0} must be at least 5 chars" />
						<o:validator validatorId="javax.faces.RegularExpression" pattern="\d+" message="{0} must contain digits only" />
					</h:inputText>
				</h:column>
			</h:dataTable>
			<h:commandButton value="Submit">
				<f:ajax execute="@form" render="@form" />
			</h:commandButton>
			<h:outputText value="OK!" rendered="#{facesContext.postback and not facesContext.validationFailed}" />
		</h:form>
	</ui:define>
</ui:composition>